/******************************************************************************
 * * ui_log.c - implementation of UI log output functions
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/
#include "ui_log.h"

static BOOL Is_OutPut(UI_SUB_MODULE_ID SubModuleId, UI_LOG_LEVEL LogLevel)
{
    if (UI_LOG_OUTPUT_LEVEL <= LogLevel)
    {
        if (UI_LOG_FILTER_BITMAP & BITPOS(SubModuleId))
        {
            return(TRUE);
        }
    }
    return(FALSE);
}

VOID UI_Log_Out(UI_SUB_MODULE_ID SubModuleId, UI_LOG_LEVEL LogLevel, INT8 *OutString, ...)
{
    INT8        *LogMessage;
    va_list     argument_ptr;
    INT32       LogSize;
    hal_rtc_t   Time;
    static BOOL ReturnFlg = 1;

    /* output trace if flag is set */
    if (Is_OutPut(SubModuleId, LogLevel))
    {
        /* Copy Trace string */
        va_start(argument_ptr,OutString);
        LogMessage = (INT8 *)Hal_Mem_Alloc(UI_LOG_MAX_SIZE +
            UI_LOG_MODULE_NAME_LEN +
            UI_LOG_TIMESTAMP_LEN);
        Hal_Rtc_Gettime(&Time);

        if (TRUE == ReturnFlg)
        {
            memset(LogMessage, ' ', UI_LOG_MODULE_NAME_LEN + UI_LOG_TIMESTAMP_LEN);          // format with space
            sprintf(LogMessage, "[%.2d:%.2d:%.2d]", Time.tm_hour, Time.tm_min, Time.tm_sec); // set timestamp

            // set sub-module name
            switch (SubModuleId)
            {
            case UI_SUB_MODULE_FRAMEWORK:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[Framework]", strlen("[Framework]"));
                break;

            case UI_SUB_MODULE_CALL:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[Call]", strlen("[Call]"));
                break;

            case UI_SUB_MODULE_CALL_LOG:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[Call_Log]", strlen("[Call_Log]"));
                break;

            case UI_SUB_MODULE_SMS:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[SMS]", strlen("[SMS]"));
                break;

            case UI_SUB_MODULE_SETTING:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[Setting]", strlen("[Setting]"));
                break;

            case UI_SUB_MODULE_CONTACT:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[Contact]", strlen("[Contact]"));
                break;

            case UI_SUB_MODULE_CALCULATOR:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[Calculator]", strlen("[Calculator]"));
                break;

            case UI_SUB_MODULE_CALENDAR:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[Calendar]", strlen("[Calendar]"));
                break;

            case UI_SUB_MODULE_ALARM:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[Alarm]", strlen("[Alarm]"));
                break;

            case UI_SUB_MODULE_MODEM_ADP:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[ModemAdp]", strlen("[ModemAdp]"));
                break;

            case UI_SUB_MODULE_COMMON_UI:
                memcpy(LogMessage + UI_LOG_TIMESTAMP_LEN, "[CommonUI]", strlen("[CommonUI]"));
                break;

            default:
                break;
            } /* switch */
            LogSize = vsnprintf(LogMessage + UI_LOG_TIMESTAMP_LEN + UI_LOG_MODULE_NAME_LEN,
                UI_LOG_MAX_SIZE, OutString, argument_ptr);
        }
        else
        {
            LogSize = vsnprintf(LogMessage, UI_LOG_MAX_SIZE, OutString, argument_ptr);
        }

        if (*(OutString + strlen(OutString) - 1) == '\n')
        {
            // one line has only one header
            ReturnFlg = TRUE;
        }
        else
        {
            ReturnFlg = FALSE;
        }

        va_end(argument_ptr);

        if (LogSize < 0) /* Buffer size is too small, LogSize is the buffer size */
        {
            LogSize = UI_LOG_MAX_SIZE;
        }

#if UI_LOG_ON_PC
        printf("%s", LogMessage);
#else
        Hal_Uart_Send_Data(UI_LOG_DEVICE, LogMessage, LogSize);
#endif

        Hal_Mem_Free(LogMessage);
    }
} /* UI_Log_Out */
